package com.warski.wonderfires.utils.date;

import com.warski.wonderfires.utils.Logger;
import com.warski.wonderfires.utils.StringUtils;
import com.warski.wonderfires.utils.json.JsonObj;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by xuhaiping on 2020/7/13.
 */
public class DateUtils {
    public static final String DEFAULT_TIMESTAMP_FORMAT = "yyyy-MM-dd HH:mm:ss";
    public static final String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";

    public static class TimestampInfo {
        public TimestampInfo()
        {}

        protected long days;
        protected long hours;
        protected long min;
        protected long second;
        protected long totalSecond;

        public long getDays() {
            return days;
        }

        public void setDays(long days) {
            this.days = days;
        }

        public long getHours() {
            return hours;
        }

        public void setHours(long hours) {
            this.hours = hours;
        }

        public long getMin() {
            return min;
        }

        public void setMin(long min) {
            this.min = min;
        }

        public long getSecond() {
            return second;
        }

        public void setSecond(long second) {
            this.second = second;
        }

        public long getTotalSecond() {
            return totalSecond;
        }

        public void setTotalSecond(long totalSecond) {
            this.totalSecond = totalSecond;
        }
    }

    public static class DateInfo extends JsonObj {
        private int year;
        private int month;
        private int day;
        private int hour;
        private int minute;
        private int second;
        private int weekOfYear;
        private int weekOfMonth;
        private int dayOfYear;

        public int getSecond() {
            return second;
        }

        public void setSecond(int second) {
            this.second = second;
        }

        public int getYear() {
            return year;
        }

        public void setYear(int year) {
            this.year = year;
        }

        public int getMonth() {
            return month;
        }

        public void setMonth(int month) {
            this.month = month;
        }

        public int getDay() {
            return day;
        }

        public void setDay(int day) {
            this.day = day;
        }

        public int getHour() {
            return hour;
        }

        public void setHour(int hour) {
            this.hour = hour;
        }

        public int getMinute() {
            return minute;
        }

        public void setMinute(int minute) {
            this.minute = minute;
        }

        public int getWeekOfYear() {
            return weekOfYear;
        }

        public void setWeekOfYear(int weekOfYear) {
            this.weekOfYear = weekOfYear;
        }

        public int getWeekOfMonth() {
            return weekOfMonth;
        }

        public void setWeekOfMonth(int weekOfMonth) {
            this.weekOfMonth = weekOfMonth;
        }

        public int getDayOfYear() {
            return dayOfYear;
        }

        public void setDayOfYear(int dayOfYear) {
            this.dayOfYear = dayOfYear;
        }

        public DateInfo(Calendar cal){
            year = cal.get(Calendar.YEAR);
            month = (cal.get(Calendar.MONTH)) + 1;
            day = cal.get(Calendar.DAY_OF_MONTH);
            hour = cal.get(Calendar.HOUR_OF_DAY);
            minute = cal.get(Calendar.MINUTE);
            second = cal.get(Calendar.SECOND);
            weekOfYear = cal.get(Calendar.WEEK_OF_YEAR);
            weekOfMonth = cal.get(Calendar.WEEK_OF_MONTH);
            dayOfYear = cal.get(Calendar.DAY_OF_YEAR);
        }
    }

    public static Date str2Date(String str, String format) {
        if (null == str || "".equals(str))
            return null;

        SimpleDateFormat sdf = new SimpleDateFormat(format);
        Date date = null;
        try {
            date = sdf.parse(str);
            return date;
        } catch (ParseException e) {
            Logger.error("解析日期错误 : " + str);
        }
        return null;
    }

    public static String date2Str(Date date, String format) {
        if (null == date)
            return null;

        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(date);
    }

    public static String timestamp2Str(Timestamp time, String format) {
        Date date = new Date(time.getTime());
        return date2Str(date, format == null ? DEFAULT_TIMESTAMP_FORMAT : format);
    }

    public static Timestamp str2Timestamp(String str, String format) {
        Date date = str2Date(str, format == null ? DEFAULT_TIMESTAMP_FORMAT : format);
        return new Timestamp(date.getTime());
    }

    public static String getNowTime() {
        return getNowTime(null, null, null);
    }

    public static String getNowTime(String timeFormat) {
        return getNowTime(timeFormat, null, null);
    }

    public static String getNowTime(String timeFormat, Locale locale) {
        return getNowTime(timeFormat, null, locale);
    }

    public static String getNowTime(String timeFormat, Float timeZoneOffset){
        return getNowTime(timeFormat, timeZoneOffset, null);
    }

    /**
     * 获取当前时间
     * @param timeFormat
     * @param timeZoneOffset
     * @param locale
     * @return
     */
    public static String getNowTime(String timeFormat, Float timeZoneOffset, Locale locale){
        SimpleDateFormat sdf;
        if(locale != null){
            sdf = new SimpleDateFormat(StringUtils.isNotEmpty(timeFormat) ? timeFormat : "yyyy-MM-dd HH:mm:ss", locale);
        }
        else{
            sdf = new SimpleDateFormat(StringUtils.isNotEmpty(timeFormat) ? timeFormat : "yyyy-MM-dd HH:mm:ss");
        }
        if(timeZoneOffset != null) {
            if (timeZoneOffset > 13 || timeZoneOffset < -12) {
                timeZoneOffset = 0.f;
            }

            int newTime = (int) (timeZoneOffset * 60 * 60 * 1000);
            TimeZone timeZone;
            String[] ids = TimeZone.getAvailableIDs(newTime);
            if (ids.length == 0) {
                timeZone = TimeZone.getDefault();
            } else {
                timeZone = new SimpleTimeZone(newTime, ids[0]);
            }

            sdf.setTimeZone(timeZone);
        }
        Date date = new Date();
        String result = sdf.format(date);

//        if(result.contains("W")){
//            Calendar cal = Calendar.getInstance();
//            cal.setTime(date);
//
//            int dayOfWeek = 1;
//            dayOfWeek = cal.get(Calendar.DAY_OF_WEEK) - 1;
//            if (dayOfWeek < 1) {
//                dayOfWeek = 7;
//            }
//
//            result = result.replaceAll("W", String.valueOf(dayOfWeek));
//        }

        return result;
    }

    /**
     * 获取当前毫秒
     * @return
     */
    public static Long getNowMilliseconds(){
        Date date = new Date();
        return date.getTime();
    }

    /**
     * 获取两个时间的差
     * @param dateNew
     * @param dateOld
     * @param format
     * @return
     */
    public static TimestampInfo getDateDiff(String dateNew, String dateOld, String format) {
        TimestampInfo info = new TimestampInfo();
        DateFormat df = new SimpleDateFormat(format);
        try {
            Date d1 = df.parse(dateNew);
            Date d2 = df.parse(dateOld);
            long l = d1.getTime() - d2.getTime();
            info.setTotalSecond(l / 1000);

            long day = l / (24 * 60 * 60 * 1000);
            long hour = (l / (60 * 60 * 1000) - day * 24);
            long min = ((l / (60 * 1000)) - day * 24 * 60 - hour * 60);
            long s = (l / 1000 - day * 24 * 60 * 60 - hour * 60 * 60 - min * 60);

            info.setDays(day);
            info.setHours(hour);
            info.setMin(min);
            info.setSecond(s);
        } catch (Exception e) {
            Logger.error(e);
        }
        return info;
    }

    /**
     * 再给出的时间上增加若干天
     * @param timeFormat
     * @param dateTime
     * @param day
     * @return
     */
    public static String addDay(String timeFormat, String dateTime, int day) {
        Date date = str2Date(dateTime, timeFormat.length() > 0 ? timeFormat : "yyyy-MM-dd HH:mm:ss");
        long time = (date.getTime() / 1000) + 60 * 60 * 24 * day;// 秒
        date.setTime(time * 1000);// 毫秒
        SimpleDateFormat df = new SimpleDateFormat(timeFormat.length() > 0 ? timeFormat : "yyyy-MM-dd HH:mm:ss");
        return df.format(date);
    }

    /**
     * 在给出的时间上增加若干秒
     * @param timeFormat
     * @param dateTime
     * @param seconds
     * @return
     */
    public static String addSecond(String timeFormat, String dateTime, int seconds) {
        Date date = str2Date(dateTime, timeFormat.length() > 0 ? timeFormat : "yyyy-MM-dd HH:mm:ss");
        long time = (date.getTime() / 1000) + seconds;// 秒
        date.setTime(time * 1000);// 毫秒
        SimpleDateFormat df = new SimpleDateFormat(timeFormat.length() > 0 ? timeFormat : "yyyy-MM-dd HH:mm:ss");
        return df.format(date);
    }
}
